import { Inject, Provide } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { QrcodeQrcodeEntity } from '../entity/qrcode';
import { PluginService } from '../../plugin/service/info';
import { BaseSysUserEntity } from '../../base/entity/sys/user';
import { QrcodeBehaveLogEntity } from '../entity/behaveLog';
import { DictInfoEntity } from '../../dict/entity/info';
import axios from 'axios'; // 需要安装 axios
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import { pUploadPath } from '../../../comm/path';

/**
 * 二维码信息
 */
@Provide()
export class QrcodeQrcodeService extends BaseService {
  @InjectEntityModel(QrcodeQrcodeEntity)
  qrcodeQrcodeEntity: Repository<QrcodeQrcodeEntity>;

  @Inject()
  pluginService: PluginService;

  @InjectEntityModel(BaseSysUserEntity)
  baseSysUserEntity: Repository<BaseSysUserEntity>;

  @InjectEntityModel(QrcodeBehaveLogEntity)
  qrcodeBehaveLogEntity: Repository<QrcodeBehaveLogEntity>;

  @InjectEntityModel(DictInfoEntity)
  dictInfoEntity: Repository<DictInfoEntity>;

  @Inject()
  ctx;

  // 重写page方法
  async page(query, options) {
    const result = await super.page(query, options);
    const users = await this.baseSysUserEntity.find();
    const dictArr = await this.dictInfoEntity.find();
    // 拼写渠道和销售
    for (const item of result.list) {
      item.channelName = dictArr.find(dict => dict.id == item.channelId)?.name || '';
      item.salesName = users.find(user => user.id === item.adminId)?.name || '';
      item.daren = item.daren || '';
      item.qrLongName = item.salesName + '-' + item.channelName + '-' + item.daren;
    }
    return result;
  }

  // 添加行为数据
  async addBehaveLog(param) {
    const result = await this.qrcodeBehaveLogEntity.save(param);
    return result;
  }

  // 根据qrcode的id获取信息
  async getQRCodeInfo(id) {
    const qrcode = await this.qrcodeQrcodeEntity.findOne({ where: { id } });
    if (!qrcode) {
      throw new Error('二维码不存在');
    }
    // 由于 QrcodeQrcodeEntity 上不存在 adminQrCode 属性，可通过对象展开并添加新属性的方式返回
    let adminUrl = '';
    if (qrcode.adminId) {
      const admin = await this.baseSysUserEntity.findOneBy({ id: qrcode.adminId });
      if (admin) {
        adminUrl = admin.qrcodeUrl;
      }
    }
    const result = { ...qrcode, adminQrCode: adminUrl };
    return result;
  }

  async add(param) {
    // 如果用户和渠道是一样的，则提示已存在
    const qrcode = await this.qrcodeQrcodeEntity.findOne({ where: { adminId: param.adminId, channelId: param.channelId } });
    if (qrcode) {
      throw new Error('二维码已存在');
    }
    const result = await super.add(param) as { id: string };
    const result2 = await this.makeQrcode(result.id);
    return result;
  }

  // 生成自定义参数二维码
  async makeCustomQrcode(scene) {
    
    // 获取插件实例
    const instance  = await this.pluginService.getInstance('wx');

    // 获取小程序实例
    const wxApp = await instance.MiniApp();

    // 获取access_token
    const accessToken = await wxApp.getAccessToken();
    const token = await accessToken.getToken();

    // 构造请求 URL
    const url = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${token}`;

    try {
        // 调用微信接口时使用buffer模式获取响应
        const response = await axios.post(url, {
            "page": "pages/index/index",
            "scene": scene
        }, {
            responseType: 'arraybuffer', // 关键设置：获取二进制buffer
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${accessToken}`
            }
        });

        // 直接使用响应buffer，避免字符串转换
        const imageBuffer = Buffer.from(response.data);

        // 移除JSON解析逻辑（二进制buffer无法解析为JSON）
        let mimeType = 'image/png';
        const header = imageBuffer.toString('hex', 0, 8).toLowerCase();
        
        // 增强文件头检测
        if (header.startsWith('89504e47')) {
            mimeType = 'image/png';
        } else if (header.startsWith('ffd8ffe0') || header.startsWith('ffd8ffe1') || header.startsWith('ffd8ffe2')) {
            mimeType = 'image/jpeg';
        } else if (header.includes('4a464946')) {
            // 检测JPEG文件标识 (JFIF)
            mimeType = 'image/jpeg';
        } else {
            // 输出详细调试信息
            console.error('原始文件头十六进制:', imageBuffer.toString('hex', 0, 32));
            console.error('原始文件头ASCII:', imageBuffer.toString('ascii', 0, 32));
            throw new Error(`无效图片格式，文件头: ${header.substring(0, 16)}`);
        }

        const tempFilePath = path.join(os.tmpdir(), `qrcode_${Date.now()}.${mimeType.split('/')[1]}`);
        fs.writeFileSync(tempFilePath, imageBuffer);

        // 上传到阿里云OSS
        const key = `tempCode/${Date.now()}.png`; // 可以根据需要调整路径
        const uploadResult = await this.pluginService.invoke('upload', 'uploadWithKey', tempFilePath, key);
        fs.unlinkSync(tempFilePath); // 删除临时文件
        
        return uploadResult;
        
    } catch (error) {
        console.error('获取二维码失败:', error);
        throw error;
    }
  }

  // 生成门店购买二维码
  async makeShopQrcode(shopId) {
    //查看是否已经有二维码，有则提示有不用生成了
    const qrcode = await this.qrcodeQrcodeEntity.findOne({ where: {
      adminId: this.ctx.admin?.userId,
      shopId: shopId,
      type: 1,
    }});
    if (qrcode) {
      return qrcode.qrcodeUrl;
    }
    // 获取插件实例
    const instance  = await this.pluginService.getInstance('wx');

    // 获取小程序实例
    const wxApp = await instance.MiniApp();

    // 获取access_token
    const accessToken = await wxApp.getAccessToken();
    const token = await accessToken.getToken();

    // 构造请求 URL
    const url = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${token}`;

    try {
        // 调用微信接口时使用buffer模式获取响应
        const response = await axios.post(url, {
            "page": "pages/index/index",
            "scene": "shopId:" + shopId
        }, {
            responseType: 'arraybuffer', // 关键设置：获取二进制buffer
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${accessToken}`
            }
        });

        // 直接使用响应buffer，避免字符串转换
        const imageBuffer = Buffer.from(response.data);

        // 移除JSON解析逻辑（二进制buffer无法解析为JSON）
        let mimeType = 'image/png';
        const header = imageBuffer.toString('hex', 0, 8).toLowerCase();
        
        // 增强文件头检测
        if (header.startsWith('89504e47')) {
            mimeType = 'image/png';
        } else if (header.startsWith('ffd8ffe0') || header.startsWith('ffd8ffe1') || header.startsWith('ffd8ffe2')) {
            mimeType = 'image/jpeg';
        } else if (header.includes('4a464946')) {
            // 检测JPEG文件标识 (JFIF)
            mimeType = 'image/jpeg';
        } else {
            // 输出详细调试信息
            console.error('原始文件头十六进制:', imageBuffer.toString('hex', 0, 32));
            console.error('原始文件头ASCII:', imageBuffer.toString('ascii', 0, 32));
            throw new Error(`无效图片格式，文件头: ${header.substring(0, 16)}`);
        }

        const tempFilePath = path.join(os.tmpdir(), `qrcode_${Date.now()}.${mimeType.split('/')[1]}`);
        fs.writeFileSync(tempFilePath, imageBuffer);

        // 上传到阿里云OSS
        const key = `shopCode/${Date.now()}.png`; // 可以根据需要调整路径
        const uploadResult = await this.pluginService.invoke('upload', 'uploadWithKey', tempFilePath, key);
        fs.unlinkSync(tempFilePath); // 删除临时文件
        
        // 拿到路径存储到数据库
        const qrcode = {
          adminId: this.ctx.admin?.userId,
          shopId: shopId,
          type: 1,
          qrcodeUrl: uploadResult,
        }
        await this.qrcodeQrcodeEntity.save(qrcode);
        return uploadResult;
        
    } catch (error) {
        console.error('获取二维码失败:', error);
        throw error;
    }
  }

  // 生成二维码
  async makeQrcode(id) {
    //查看是否已经有二维码，有则提示有不用生成了
    const qrcode = await this.qrcodeQrcodeEntity.findOne({ where: { id } });
    if (qrcode.qrcodeUrl) {
      throw new Error('二维码已存在');
    }


    // 获取插件实例
    const instance  = await this.pluginService.getInstance('wx');

    // 获取小程序实例
    const wxApp = await instance.MiniApp();

    // 获取access_token
    const accessToken = await wxApp.getAccessToken();
    const token = await accessToken.getToken();

    // 构造请求 URL
    const url = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${token}`;

    

    try {
        // 发送 POST 请求

        // 调用微信接口时使用buffer模式获取响应
        const response = await axios.post(url, {
            "page": "pages/index/activeInvite",
            "scene": "qrcodeId:" + id
        }, {
            responseType: 'arraybuffer', // 关键设置：获取二进制buffer
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${accessToken}`
            }
        });

        // 直接使用响应buffer，避免字符串转换
        const imageBuffer = Buffer.from(response.data);

        // 移除JSON解析逻辑（二进制buffer无法解析为JSON）
        let mimeType = 'image/png';
        const header = imageBuffer.toString('hex', 0, 8).toLowerCase();
        
        // 增强文件头检测
        if (header.startsWith('89504e47')) {
            mimeType = 'image/png';
        } else if (header.startsWith('ffd8ffe0') || header.startsWith('ffd8ffe1') || header.startsWith('ffd8ffe2')) {
            mimeType = 'image/jpeg';
        } else if (header.includes('4a464946')) {
            // 检测JPEG文件标识 (JFIF)
            mimeType = 'image/jpeg';
        } else {
            // 输出详细调试信息
            console.error('原始文件头十六进制:', imageBuffer.toString('hex', 0, 32));
            console.error('原始文件头ASCII:', imageBuffer.toString('ascii', 0, 32));
            throw new Error(`无效图片格式，文件头: ${header.substring(0, 16)}`);
        }

        const tempFilePath = path.join(os.tmpdir(), `qrcode_${Date.now()}.${mimeType.split('/')[1]}`);
        fs.writeFileSync(tempFilePath, imageBuffer);

        // 上传到阿里云OSS
        const key = `salesCode/${Date.now()}.png`; // 可以根据需要调整路径
        const uploadResult = await this.pluginService.invoke('upload', 'uploadWithKey', tempFilePath, key);
        fs.unlinkSync(tempFilePath); // 删除临时文件
        
        // 拿到路径存储到数据库
        const qrcode = await this.qrcodeQrcodeEntity.findOne({ where: { id } });
        qrcode.qrcodeUrl = uploadResult;
        await this.qrcodeQrcodeEntity.save(qrcode);
        return true;
        
    } catch (error) {
        console.error('获取二维码失败:', error);
        throw error;
    }
  }
}
